package logical;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Vector;

import javax.swing.JFrame;

import cflow.Cflow;

public class DFA {
	private Vector<SetState> states;
	private SetState initialState;
	private boolean showGraph = true;

	public SetState getInitialState() {
		return initialState;
	}

	public void setInitialState(SetState initialState) {
		this.initialState = initialState;
	}

	public State automataFinalState;
	private AutomataVisualizer visualizer;

	public DFA(Automata automata, Cflow cflow) {
		initDFA(automata);
	}

	public DFA(Automata automata) {
		initDFA(automata);
	}

	private void initDFA(Automata automata) {
		 
		Vector<State> set = new Vector<State>();
		states = new Vector<SetState>();
		automataFinalState = automata.getFinalState();
		initialState = new SetState(automata.getInitialState().statesReachable(
				set),this);
		states.add(initialState);

		for (int i = 0; i < states.size(); i++) {
			SetState tmp_state = states.get(i);
			Vector<String> transitions = tmp_state.listTransitions();

			for (int j = 0; j < transitions.size(); j++) {
				set = new Vector<State>();
				set = tmp_state.setStateReachable(transitions.get(j));

				SetState newSetState = new SetState(set,this);
				if (states.contains(newSetState)) {
					int index = states.indexOf(newSetState);
					tmp_state.getTransitions().add(
							new TransitionDFA(states.get(index), transitions
									.get(j)));
				} else {
					states.add(newSetState);
					tmp_state.getTransitions().add(
							new TransitionDFA(newSetState, transitions.get(j)));
				}
			}

		}
	}

	public void createVisualization(boolean showGraph) {
		this.showGraph = showGraph;
		visualizer = new AutomataVisualizer();
		initialState.visited = true;

		Queue<SetState> states = new LinkedList<SetState>();
		states.add(initialState);
		initialState.vertexNo = visualizer.addVertex();

		if (initialState.isFinal())
			visualizer.getFinalVertex().add(String
					.valueOf(initialState.vertexNo));

		visualizer.currState = initialState;

		while (!states.isEmpty()) {
			SetState temp = states.poll();
			for (int i = 0; i < temp.getTransitions().size(); i++) {
				TransitionDFA trans = temp.getTransitions().get(i);
				if (!trans.visited) {
					trans.visited = true;
					SetState dest = trans.getDestinationState();

					if (!dest.visited) {
						states.add(dest);
						dest.vertexNo = visualizer.addVertex();
						if (dest.isFinal())
							visualizer.getFinalVertex().add(String
									.valueOf(dest.vertexNo));
						dest.visited = true;
					}
					visualizer.addEdge(trans.getValue(), temp.vertexNo,
							dest.vertexNo);
				}
			}
		}

		if (showGraph) {
			visualizer.view(1024, 700);
		}
	}

	public void refresh(SetState s) {
		visualizer.currState = s;
		if (showGraph) {
			visualizer.frame.pack();
			visualizer.frame.repaint();
		}
	}

	public void setName(String input) {
		visualizer.frame.setTitle(input);
	}

}
